﻿using ESPL.CodeGenerator.Common;
using ESPL.CodeGenerator.Common.ProjectBuilders;
using System;
using ESPL.CodeGenerator.Domain.TemplateGenerators.CSharpCodeGenerators;
using ESPL.CodeGenerator.Common.Structs;
using System.Collections.Generic;
using ESPL.CodeGenerator.Common.Generators;
using ESPL.CodeGenerator.Domain.Utilities;
using ESPL.CodeGenerator.Common.Enums;

namespace ESPL.CodeGenerator.Domain.ProjectBuilders
{
    internal abstract class CodeBuilderBase : ICodeBuilder
    {
        #region Declarations

        private ICodeBuilder _successor = null;
        private ApplicationConfiguration _config;
        protected IBaseGenerator _generator;

        #endregion

        #region Constructor

        internal CodeBuilderBase(ApplicationConfiguration config)
        {
            _config = config;
        }

        #endregion

        #region Properties

        public ICodeBuilder Successor
        {
            get
            {
                return _successor;
            }
            set
            {
                _successor = value;
            }
        }

        protected ApplicationConfiguration Config
        {
            get
            {
                return _config;
            }
        }

        protected bool CreateDir { get; set; }

        protected bool WriteFile { get; set; }

        #endregion

        #region Methods

        public virtual IList<IBuilderResponse> ProcessRequest(IProjectBuilderRequest request)
        {
            var response = new List<IBuilderResponse>();
            if (Successor != null)
                response.AddRange(Successor.ProcessRequest(request));
            return response;
        }

        protected abstract void InitGenerator();

        protected abstract BuilderResponse GetResponse();

        protected virtual string GetDirectoryPath()
        {
            return string.Empty;
        }

        protected virtual string GetFilePath()
        {
            return string.Empty;
        }

        protected virtual void CreateRequiredDirectory()
        {
            if (CreateDir)
                CreateDirectory(GetDirectoryPath());
        }

        protected void CreateDirectory(string directoryPath)
        {
            DirectoryHelper.CreateDirectory(directoryPath);
        }

        protected virtual void WriteFileContents()
        {
            if (WriteFile)
                WriteFileContents(GetFilePath(), _generator);
        }

        protected void WriteFileContents(string filePath, IBaseGenerator generator)
        {
            FileHelper.CreateFile(filePath, generator.TransformText());
        }

        public virtual IList<IBuilderResponse> InitializeProjectTree()
        {
            var response = new List<IBuilderResponse>();
            InitGenerator();

            CreateRequiredDirectory();
            WriteFileContents();            

            response.Add(GetResponse());
            if (Successor != null)
                response.AddRange(Successor.InitializeProjectTree());
            return response;
        }

        protected void CopyFile(string fileName, string sourcePath,string destFileName="")
        {
            string targetPath = GetDirectoryPath();

            string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
            string destFile = System.IO.Path.Combine(targetPath, !string.IsNullOrEmpty(destFileName) ? destFileName : fileName);

            if (!System.IO.Directory.Exists(targetPath))
            {
                System.IO.Directory.CreateDirectory(targetPath);
            }

            System.IO.File.Copy(sourceFile, destFile, true);
        }

        protected void DeleteFile(string filePath)
        {
            try
            {
                System.IO.File.Delete(filePath);
            }
            catch (System.IO.IOException e)
            {
            }
        }

        protected string ProcessTransformation(string templateFilePath)
        {
            string commandToExe = string.Format(@"/C {0}Resources\TextTransform.exe {1}",Config.ResourceFolderPath,templateFilePath);
            System.Diagnostics.ProcessStartInfo PR = new System.Diagnostics.ProcessStartInfo("cmd", commandToExe);
            PR.UseShellExecute = false;
            PR.RedirectStandardOutput = true;
            PR.RedirectStandardError = true;
            PR.CreateNoWindow = true;
            System.Diagnostics.Process StartPR = new System.Diagnostics.Process();
            StartPR.StartInfo = PR;
            StartPR.Start();
            string error = StartPR.StandardError.ReadToEnd();
            StartPR.WaitForExit();
            return error;
        }

        #endregion
    }
}
